package com.kallsonys.jsf;

import com.kallsonys.object.OrderOms;
import com.kallsonys.jsf.util.JsfUtil;
import com.kallsonys.jsf.util.PaginationHelper;
import com.kallsonys.object.Creditcard;
import com.kallsonys.object.Customer;
import com.kallsonys.object.Orderquote;
import com.kallsonys.object.ws.ListElement;
import com.kallsonys.service.BilledMont;
import com.kallsonys.service.ElementListPage;
import com.kallsonys.service.Order;
import com.kallsonys.session.OrderOmsFacade;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.event.ActionEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

@ManagedBean(name = "orderOmsController")
@SessionScoped
public class OrderOmsController implements Serializable {

    private OrderOms current;
    private DataModel items = null;
    @EJB
    private com.kallsonys.session.OrderOmsFacade ejbFacade;
    @EJB
    private com.kallsonys.session.CreditcardFacade ejbCreditCard;
    @EJB
    private com.kallsonys.session.OrderquoteFacade ejbOrderQuote;
    private PaginationHelper pagination;
    private int selectedItemIndex;
    private long orderId;
    private long orderProductId;
    private int totalPages;
    private int currentPage;
    private Date closedEndDate;
    private Date closedStartDate;
    private List<Orderquote> lstOrderQuote;
    private int lstOrderQuoteSize;

    public List<Orderquote> getLstOrderQuote() {
        if (current != null) {
            lstOrderQuote = ejbOrderQuote.getByIdOrder(current.getOrderid());
        } else {
            lstOrderQuote = new ArrayList<Orderquote>();
        }
        return lstOrderQuote;
    }

    public int getLstOrderQuoteSize() {
        int retorno = 0;
        retorno = getLstOrderQuote().size();
        return retorno;
    }

    public void setLstOrderQuoteSize(int lstOrderQuoteSize) {
        this.lstOrderQuoteSize = lstOrderQuoteSize;
    }

    public void setLstOrderQuote(List<Orderquote> lstOrderQuote) {
        this.lstOrderQuote = lstOrderQuote;
    }

    public Date getClosedEndDate() {
        return closedEndDate;
    }

    public void setClosedEndDate(Date closedEndDate) {
        this.closedEndDate = closedEndDate;
    }

    public Date getClosedStartDate() {
        return closedStartDate;
    }

    public void setClosedStartDate(Date closedStartDate) {
        this.closedStartDate = closedStartDate;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }
    private int billedMonth;
    private int billedYear;
    private long totalBilled;
    private int totalOrdersBilled;

    public int getBilledMonth() {
        return billedMonth;
    }

    public void setBilledMonth(int billedMonth) {
        this.billedMonth = billedMonth;
    }

    public int getBilledYear() {
        return billedYear;
    }

    public void setBilledYear(int billedYear) {
        this.billedYear = billedYear;
    }

    public long getTotalBilled() {
        return totalBilled;
    }

    public void setTotalBilled(long totalBilled) {
        this.totalBilled = totalBilled;
    }

    public int getTotalOrdersBilled() {
        return totalOrdersBilled;
    }

    public void setTotalOrdersBilled(int totalOrdersBilled) {
        this.totalOrdersBilled = totalOrdersBilled;
    }

    public long getOrderProductId() {
        return orderProductId;
    }

    public void setOrderProductId(long orderProductId) {
        this.orderProductId = orderProductId;
    }
    private List<Order> lstOrders;
    private List<Order> lstOpenOrders;
    private List<Order> lstClosedOrders;

    public List<Order> getLstClosedOrders() {
        if (lstClosedOrders == null) {
            lstClosedOrders = new ArrayList<Order>();
        }
        return lstClosedOrders;
    }

    public void setLstClosedOrders(List<Order> lstClosedOrders) {
        this.lstClosedOrders = lstClosedOrders;
    }

    public int getLstClosedOrdersSize() {
        return getLstClosedOrders().size();
    }

    public List<Order> getLstOpenOrders() {
        if (lstOpenOrders == null) {
            lstOpenOrders = new ArrayList<Order>();
        }
        return lstOpenOrders;
    }

    public void setLstOpenOrders(List<Order> lstOpenOrders) {
        this.lstOpenOrders = lstOpenOrders;
    }

    public int getLstOpenOrdersSize() {
        return getLstOpenOrders().size();
    }

    public List<Order> getLstOrders() {
        if (lstOrders == null) {
            lstOrders = new ArrayList<Order>();
        }
        return lstOrders;
    }

    public void setLstOrders(List<Order> lstOrders) {
        this.lstOrders = lstOrders;
    }

    public int getLstSize() {
        return getLstOrders().size();
    }

    public long getOrderId() {
        return orderId;
    }

    public void setOrderId(long orderId) {
        this.orderId = orderId;
    }

    public OrderOmsController() {
    }

    public OrderOms getSelected() {
        if (current == null) {
            current = new OrderOms();
            selectedItemIndex = -1;
        }
        return current;
    }

    public String getCurrentCustomer() {
        if (current != null) {
            return current.getCustomerid().getCustomerfirstname()
                    + " "
                    + current.getCustomerid().getCustomerlastname()
                    + " " + current.getCustomerid().getCustomerdocument();
        }

        return "";
    }

    public String getCurrentAddress() {
        if (current != null) {
            return current.getAddressid().getAddressstreet()
                    + " "
                    + current.getAddressid().getAddresstown();

        }

        return "";
    }

    private OrderOmsFacade getFacade() {
        return ejbFacade;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return pagination;
    }

    public String getCreditCard() {

        String retorno = "";
        if (current.getCreditcardid() != null) {
            Creditcard cc = ejbCreditCard.find(current.getCreditcardid());
            retorno = cc.toString();
        }

        return retorno;
    }

    public String getCustomer() {
        return current.getCustomerid().toString();
    }

    public String getAddress() {
        return current.getAddressid().toString();
    }

    public String getShippingCompany() {
        if (current.getShippingcompanyid() != null) {
            return current.getShippingcompanyid().toString();
        }

        return "";
    }

    public String prepareList() {
        recreateModel();
        return "List";
    }

    public String prepareView() {
        current = (OrderOms) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareViewCustom() {
        current = ejbFacade.getByOrderId(orderId);

        //selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareViewByProduct() {
        current = ejbFacade.getByOrderId(current.getOrderid());

        //selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareCreate() {
        current = new OrderOms();
        selectedItemIndex = -1;
        return "Create";
    }

    public String create() {
        try {
            getFacade().create(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("OrderOmsCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String prepareEdit() {
        current = (OrderOms) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Edit";
    }

    public String update() {
        
        String mensaje = "Orden Modificada";
        
        try {
            getFacade().edit(current);

            try {
                //
                if (current.getOrdersource().intValue() == 1) {
                    //Inicio el Proceso de Negocio
                    getFacade().processOrder(current.getOrderid());
                    mensaje += " -- ** Proceso de Negocio ESB Ejecutado...";
                }
            } catch (Exception e) {
                mensaje += " -- ** Proceso de Negocio Genero Problemas:  " + e.getMessage();
            }


            JsfUtil.addSuccessMessage(mensaje);
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Error Modificando la Orden");
            return null;
        }
    }

    public String destroy() {
        current = (OrderOms) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        performDestroy();
        recreateModel();
        return "List";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage("Orden Eliminada");
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Error Eliminando la Orden");
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count - 1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
        }
    }

    public String viewById() throws Exception {
        Order order = ejbFacade.getById(orderId);

        lstOrders = new ArrayList<Order>();

        lstOrders.add(order);

        return "";
    }

    public String viewBilled() throws Exception {
        BilledMont objBilled = ejbFacade.getBilledMonth(billedMonth, billedYear);

        this.totalBilled = objBilled.getTotalBilled();
        this.totalOrdersBilled = objBilled.getTotalOrders();

        return "";
    }

    public String viewByIdProduct() throws Exception {
        List<Order> orders = ejbFacade.getByIdProduct(orderProductId);

        lstOrders = orders;

        return "";
    }

    public String viewByOpenOrders() throws Exception {
        ElementListPage<Order> orders = ejbFacade.getOpenOrders(currentPage);

        lstOpenOrders = orders.getElementList();
        totalPages = orders.getPages();

        return "";
    }

    public String viewByClosedOrders() throws Exception {
        ElementListPage<Order> orders = ejbFacade.getClosedOrders(currentPage, closedStartDate, closedEndDate);

        lstClosedOrders = orders.getElementList();
        totalPages = orders.getPages();

        return "";
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public String viewDetail() throws IOException {

        FacesContext.getCurrentInstance().getExternalContext().redirect("../orderitem/List.xhtml?idOrder=" + current.getOrderid());
        return "creditcard";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    public SelectItem[] getStatusSelectOne() {

        List<ListElement> lstItems = ejbFacade.getClientCategorys();

        SelectItem[] arrItems = new SelectItem[lstItems.size()];

        for (int i = 0; i < lstItems.size(); i++) {
            arrItems[i] = new SelectItem(Long.valueOf(lstItems.get(i).getElementId()), lstItems.get(i).getElementValue());
        }

        return arrItems;
    }

    public String getStatus() {

        List<ListElement> lstItems = ejbFacade.getClientCategorys();

        String status = "";
        for (int i = 0; i < lstItems.size(); i++) {
            if (String.valueOf(current.getOrderstatus()).equals(lstItems.get(i).getElementId())) {
                status = lstItems.get(i).getElementValue();
            }
        }

        return status;
    }

    @FacesConverter(forClass = OrderOms.class)
    public static class OrderOmsControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            OrderOmsController controller = (OrderOmsController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "orderOmsController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof OrderOms) {
                OrderOms o = (OrderOms) object;
                return getStringKey(o.getOrderid());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + OrderOmsController.class.getName());
            }
        }
    }

    public String editOrder(ActionEvent evt) throws IOException {
        // We get the table object
        HtmlDataTable table = getParentDatatable((UIComponent) evt.getSource());
        // We get the object on the selected line.
        Object o = table.getRowData();

        Order order = (Order) o;

        current = new OrderOms(order.getId());
        // Eventually, if you need the index of the line, simply do:
        //int index = table.getRowIndex();

        //FacesContext.getCurrentInstance().getExternalContext().redirect("../orderOms/View.xhtml");

        return "View";
        // ...
    }

// Method to get the HtmlDataTable.
    private HtmlDataTable getParentDatatable(UIComponent compo) {
        if (compo == null) {
            return null;
        }
        if (compo instanceof HtmlDataTable) {
            return (HtmlDataTable) compo;
        }
        return getParentDatatable(compo.getParent());
    }
}
